#pragma once

#include "noncopyable.h"
#include <vector>
#include <deque>
#include "task.h"
#include <mutex>
namespace TinyRPC{

template<typename  T>
class BlockingQueue : public Noncopyable {
public:
    T take();
    T nonBlockTake();
    void push(const T& task);
    void push(T&& task);
    void nonBlockPush(const T& task);
    bool empty(){
        return m_tasks.empty();
    }
private:
    std::deque<T> m_tasks;
    std::mutex m_mutex;
};

template<typename  T>
T BlockingQueue<T>::take(){
    std::unique_lock<std::mutex> lock(m_mutex);
    T t(std::move(m_tasks.front()));
    m_tasks.pop_front();
    return t;
}

template<typename  T>
T BlockingQueue<T>::nonBlockTake(){
    T t(std::move(m_tasks.front()));
    m_tasks.pop_front();
    return t;
}
template<typename  T>
void BlockingQueue<T>::push(const T& task){
    std::unique_lock<std::mutex> lock(m_mutex);
    m_tasks.push_back(task);
}


template<typename  T>
void BlockingQueue<T>::nonBlockPush(const T& task){
  
    m_tasks.push_back(task);
}
template<typename  T>
void BlockingQueue<T>::push(T&& task){
    std::unique_lock<std::mutex> lock(m_mutex);
    m_tasks.push_back(std::move(task));
}
}
